﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DPS.Prototype.PolicyBase;
using DPS.Prototype.Model;
using DPS.Prototype.PolicyBase.Manager;

namespace DPS.Prototype.Policy
{
    public class DefaultPolicyMaker:PolicyMakerBase
    {
        private class SubmitResultCompare : IEqualityComparer<SubmitResult>
        {
            public bool Equals(SubmitResult x, SubmitResult y)
            {
                return x.WorkOrder.CompareTo(y.WorkOrder)==0;
            }

            public int GetHashCode(SubmitResult obj)
            {
                return obj.WorkOrder.OrderNo.GetHashCode();
            }
        }

        protected override List<PolicyOrder> MakePolicy()
        {
            int currentCycle = base.CurrentCycle;
            List<PolicyOrder> listPolicy = new List<PolicyOrder>();
            Dictionary<string, Submission> currentCycleSubmissions = PolicyMakerBase._innerSubmissions[currentCycle];
            if (EnsureSumissionCounts(currentCycleSubmissions))
            {
                List<SubmitResult> distinctResults= currentCycleSubmissions.Values.Where(m=>m.Result!=null).Select(m=>m.Result).Distinct(new SubmitResultCompare()).ToList();
                distinctResults.ForEach(result =>
                {
                    if (result != null)
                    {
                        var query = currentCycleSubmissions.Where(mission =>  mission.Value.Result!=null && mission.Value.Result.WorkOrder.OrderNo == result.WorkOrder.OrderNo);
                        Submission assignedSubmission = null;
                        if (query.Count() == 1)
                        {
                            assignedSubmission = query.First().Value;
                        }
                        else
                        {
                            assignedSubmission = query.OrderBy(m => m.Value.Result.FinishTime).First().Value;
                        }
                        if (assignedSubmission != null)
                        {
                            PolicyOrder policy = ConstructApproveOrder(assignedSubmission);
                            listPolicy.Add(policy);
                        }
                    }
                });
            }
            return listPolicy;
        }


        private PolicyOrder ConstructApproveOrder(Submission subMission)
        {
            PolicyOrder policy = new PolicyOrder(OrderType.ApproveThisCycle);
            policy.Submission = subMission;
            return policy;
        }
    


        private bool EnsureSumissionCounts( Dictionary<string, Submission> currentCycleSubmissions)
        {
            return currentCycleSubmissions.Count == ProdCompetitorAllianceManager.Current.ProdCompetiorCounts;
        }
    }
}
